<template>
  <el-dialog
    title="用户注册"
    center
    :visible.sync="dialogVisible"
    width="600px"
  >
    <el-form
      :model="form"
      ref="form"
      :rules="rules"
      label-width="80px"
      :inline="false"
      size="normal"
      label-position="left"
    >
      <el-form-item label="头像" prop="avatar">
        <el-upload
          class="avatar-uploader"
          :data="imageObj"
          :action="uploadUrl"
          :show-file-list="false"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
        >
          <img v-if="imageUrl" :src="imageUrl" class="avatar" />
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </el-form-item>
      <el-form-item label="昵称" prop="username">
        <el-input v-model="form.username"></el-input>
      </el-form-item>
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="form.email"></el-input>
      </el-form-item>
      <el-form-item label="手机" prop="phone">
        <el-input v-model="form.phone"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input v-model="form.password" show-password></el-input>
      </el-form-item>
      <el-row>
        <el-col :span="16">
          <el-form-item label="图形码" prop="code">
            <el-input v-model="form.code"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="7" style="margin-left:10px"
          ><img :src="codeURL" alt="" style="width:100%" @click="getCode" />
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="16">
          <el-form-item label="验证码" prop="rcode">
            <el-input v-model="form.rcode"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="7" style="margin-left:10px">
          <el-button style="width:100%" @click="getCaptcha"
            >获取验证码</el-button
          >
        </el-col>
      </el-row>
    </el-form>

    <span slot="footer" class="dialog-footer">
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="register">确 定</el-button>
    </span>
  </el-dialog>
</template>
<script>
export default {
  data () {
    return {
      codeURL:
        process.env.VUE_APP_BASEURL + '/captcha?type=sendsms' /* 图形码地址 */,
      dialogVisible: false,
      imageUrl: '' /* 实现图片预览时图片的src值 */,
      uploadUrl:
        process.env.VUE_APP_BASEURL + '/uploads' /* 将文件上传到哪里 */,
      imageObj: {},
      form: {
        username: '',
        phone: '',
        email: '',
        avatar: '',
        password: '',
        code: '',
        rcode: ''
      },
      rules: {
        avatar: [
          { required: true, message: '头像不能为空', trigger: 'change' }
        ],
        username: [
          { required: true, message: '昵称不能为空', trigger: 'blur' }
        ],
        email: [
          {
            required: true,
            validator: (rule, value, callback) => {
              // rule：规则，一般不用
              // value：用户输入的值
              // callback：回调函数，无论验证是否通过都要执行
              if (!value) return callback(new Error('邮箱不能为空'))
              // 下一行不受vue书写规范影响
              // eslint-disable-next-line
              const reg = /^([a-zA-Z\d])(\w|\-)+@[a-zA-Z\d]+\.[a-zA-Z]{2,4}$/
              if (!reg.test(value)) return callback(new Error('邮箱格式不合法'))
              callback()
            },
            trigger: 'blur'
          }
        ],
        phone: [
          {
            required: true,
            validator: (rule, value, callback) => {
              // rule：规则，一般不用
              // value：用户输入的值
              // callback：回调函数，无论验证是否通过都要执行
              if (!value) return callback(new Error('手机号不能为空'))
              // 下一行不受vue书写规范影响
              // eslint-disable-next-line
              const reg = /^1[3-9][0-9]{9}$/
              if (!reg.test(value)) return callback(new Error('手机号不合法'))
              callback()
            },
            trigger: 'blur'
          }
        ],
        password: [
          { required: true, message: '密码不能为空', trigger: 'blur' },
          { min: 8, max: 16, message: '密码长度为8-16位', trigger: 'blur' }
        ],
        code: [
          { required: true, message: '图形码不能为空', trigger: 'blur' },
          { min: 4, max: 4, message: '图形码长度为4位', trigger: 'blur' }
        ],
        rcode: [
          { required: true, message: '验证码不能为空', trigger: 'blur' },
          { min: 4, max: 4, message: '验证码长度为4位', trigger: 'blur' }
        ]
      }
    }
  },
  watch: {
    dialogVisible: {
      deep: true,
      handler: function (newValue) {
        if (newValue === false) {
          this.$refs.form.resetFields()
        }
      }
    }
  },
  methods: {
    // 头像上传成功的事件
    handleAvatarSuccess (res, file) {
      // res:上传成功后返回的数据
      // file:上传的文件
      // 以上的值不需要传参，上传前工作成功完成后自动返回

      // 实现图片预览功能
      this.imageUrl = URL.createObjectURL(file.raw)
      // 并保存文件地址(给表单中的avatar赋值)
      this.form.avatar = res.data.file_path
    },
    // 头像上传前的事件
    beforeAvatarUpload (file) {
      // 限定文件的格式
      const isJPG = file.type === 'image/jpeg' || 'image/png' || 'image/gif'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        this.$message.error('上传头像图片必须是是 JPG/PNG/GIF 格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
      }
      // 项目规定上传前要携带image文件参数，返回上传后的文件地址
      this.imageObj.image = file
      return isJPG && isLt2M
    },
    // 图形码被点击时会更换
    getCode () {
      this.codeURL =
        process.env.VUE_APP_BASEURL + '/captcha?type=sendsms&t=' + Date.now()
    },
    // 获取验证码
    async getCaptcha () {
      // 1.先对图形码和手机号进行局部验证(要获取表单实例)
      let num = 0
      this.$refs.form.validateField(['phone', 'code'], res => {
        // 传入的参数是一个数组，数组中的值是要验证的项的prop值,有几个元素就验证几次
        // 当验证通过时，返回的是空，验证不通过返回的是rules里面的message
        if (!res) {
          num++
        }
      })
      // 判断验证是否通过
      if (num === 2) {
        // 验证通过，发送请求获取验证码
        const res = await this.$axios.post('/sendsms', {
          phone: this.form.phone,
          code: this.form.code
        })
        // 判断是否获取到验证码
        if (res.code === 200) {
          // 提示获取成功
          this.$message.success('验证码已发送')
          // 将获取到的验证码进行显示
          this.form.rcode = res.data.captcha
        } else {
          // 获取失败提示用户
          this.$message.error(res.message)
          // 更新验证码
          this.getCode()
        }
      } else {
        //   验证不通过时，刷新图形码
        this.getCode()
      }
    },
    // 完成注册功能
    register () {
      // 1.全局验证表单
      this.$refs.form.validate(async valid => {
        // valid：校验之后返回的boolean值
        // true:校验成功
        // false:校验失败
        if (!valid) return
        // 校验成功，根据表单信息发送请求
        const res = await this.$axios.post('/register', this.form)
        if (res.code === 200) {
          // 注册成功,提示用户
          this.$message.success('注册成功')
          // 隐藏对话框
          this.dialogVisible = false
        } else {
          // 提示用户并刷新图形码
          this.$message.error(res.message)
          this.getCode()
        }
      })
    }
  }
}
</script>
<style>
.avatar-uploader {
  text-align: center;
}
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px !important;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>
